/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package sk.adresa.eaukcia.frontend.beans;  

import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;

import org.jsflot.components.FlotChartClickedEvent;
import org.jsflot.components.FlotChartDraggedEvent;
import org.jsflot.components.FlotChartRendererData;
import org.jsflot.xydata.XYDataList;
import org.jsflot.xydata.XYDataPoint;
import org.jsflot.xydata.XYDataSetCollection;
import org.mortbay.log.Log;

public class ChartBean {
    
    private XYDataList series1DataList = new XYDataList();
    private HashMap<String, XYDataList> seriesDatalist = new HashMap<String, XYDataList>();
    private int minX = 0;
    private int maxX = 10;
    private FlotChartRendererData chartData;
    private String clickedString = "No Data Point Clicked Yet.";
    private String clickedDataPointLabel = "";
    private Integer clickedDataSeriesIndex = null;
    private XYDataPoint clickedDataPoint = null;
    private List<String> user_name;
    static List<String[][]> cc;
    
    public ChartBean() throws ParseException {
        List<String[][]> udaje = cc;
        maxX = udaje.size() - 1;
        Set<String> pom = new TreeSet<String>();
        user_name = new ArrayList<String>();
        for (int i = 0; i < udaje.size(); i++) {
            String[][] prvok = (String[][])udaje.get(i);
            String[] datum = (String[]) prvok[0];
            String[] userCena = (String[]) prvok[1];
            NumberFormat nf = NumberFormat.getNumberInstance();
            nf.setMaximumFractionDigits(3);
            SimpleDateFormat f = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
            Date d = f.parse(datum[0]);
            long milliseconds = d.getTime();
            if (seriesDatalist.isEmpty()) {
                seriesDatalist.put(userCena[0], new XYDataList());
                seriesDatalist.get(userCena[0]).setLabel(userCena[0]);
            }
            else if (!seriesDatalist.containsKey(userCena[0])) {
                seriesDatalist.put(userCena[0], new XYDataList());
                seriesDatalist.get(userCena[0]).setLabel(userCena[0]);
            }
            seriesDatalist.get(userCena[0]).addDataPoint(new XYDataPoint(milliseconds, Double.parseDouble((userCena[1]).replaceAll(",", ".")), "Cenu zmenil " + userCena[0]));
            pom.add(userCena[0]);
        }
        for (String i:pom) {
            user_name.add(i);
        }
        // TODO Auto-generated constructor stub
        chartData = new FlotChartRendererData();
        chartData.setMode("Time");
	chartData.setXaxisTitle("Datum");
	chartData.setYaxisTitle("Cena");
	chartData.setShowDataPoints(true);
	chartData.setTimeFormat("%d/%m/%y %H:%M:%S");
	chartData.setHeight("600");
	chartData.setWidth("850");
        chartData.setChartZoomable(true);
        chartData.setShowTooltip(true);
        chartData.setCrosshair("xy");
        chartData.setTooltipPosition("North West");
        
    }
    
    public List<String> getUsername() {
        return user_name;
    }
    
    public XYDataSetCollection getChartSeries() {
        XYDataSetCollection collection = new XYDataSetCollection();
        HashMap<String, XYDataList> currentSeriesDatalist = new HashMap<String, XYDataList>();
        for (int i = 0; i < seriesDatalist.size(); i++) {
            currentSeriesDatalist.put(user_name.get(i), new XYDataList());
        }
        for (int i = minX; i <= maxX; i++) {
            if (chartData.getMode().equalsIgnoreCase("Time")) {
                HashMap<String, List<XYDataPoint>> p = new HashMap<String, List<XYDataPoint>>();
                for (int j = 0; j < seriesDatalist.size(); j++) {
                    p.put(user_name.get(j), new ArrayList<XYDataPoint>());
                }
                Iterator<String> keySetIterator = seriesDatalist.keySet().iterator();
                while(keySetIterator.hasNext()){
                  String key = keySetIterator.next();
                  XYDataList pom = seriesDatalist.get(key);
                  if (pom.size() > i) {
                    XYDataPoint pom2 = pom.get(i);
                    XYDataPoint pom1 = new XYDataPoint(pom2.getX(), pom2.getY(), pom2.getPointLabel());
                    p.get(key).add(pom1);
                    XYDataPoint a = p.get(key).get(p.get(key).size()-1);
                    p.get(key).get(p.get(key).size()-1).setX((a.getX().doubleValue()));
                  }
                }
                Iterator<String> keySetIterator1 = currentSeriesDatalist.keySet().iterator();
                while(keySetIterator1.hasNext()){
                  String key = keySetIterator1.next();
                  for (int k = 0; k < p.get(key).size(); k++) {
                    currentSeriesDatalist.get(key).addDataPoint(p.get(key).get(k));
                  }
                }
            } else {
                Iterator<String> keySetIterator = seriesDatalist.keySet().iterator();
                while(keySetIterator.hasNext()){
                  String key = keySetIterator.next();
                  currentSeriesDatalist.get(key).addDataPoint(seriesDatalist.get(key).get(i));
                }
            }
            
        }
        Iterator<String> keySetIterator1 = currentSeriesDatalist.keySet().iterator();
        while(keySetIterator1.hasNext()){
            String key = keySetIterator1.next();
            currentSeriesDatalist.get(key).setLabel(seriesDatalist.get(key).getLabel());
            currentSeriesDatalist.get(key).setFillLines(seriesDatalist.get(key).isFillLines());
            currentSeriesDatalist.get(key).setMarkerPosition(seriesDatalist.get(key).getMarkerPosition());
            currentSeriesDatalist.get(key).setMarkers(seriesDatalist.get(key).isMarkers());
            currentSeriesDatalist.get(key).setShowDataPoints(seriesDatalist.get(key).isShowDataPoints());
            currentSeriesDatalist.get(key).setShowLines(seriesDatalist.get(key).isShowLines());
            collection.addDataList(currentSeriesDatalist.get(key));
        }
        
        return collection;
    }

    public FlotChartRendererData getChartData() {
        return chartData;
    }
    
    public void setChartData(FlotChartRendererData chartData) {
        this.chartData = chartData;
    }
    
    public String getClickedString() {
        return clickedString;
    }
    
    public void setClickedString(String clickedString) {
        this.clickedString = clickedString;
    }
    
    public XYDataPoint getClickedDataPoint() {
        return clickedDataPoint;
    }
    
    public void setClickedDataPoint(XYDataPoint clickedDataPoint) {
        this.clickedDataPoint = clickedDataPoint;
    }
    
    public String getClickedDataPointLabel() {
        return clickedDataPointLabel;
    }
    
    public void setClickedDataPointLabel(String clickedDataPointLabel) {
        this.clickedDataPointLabel = clickedDataPointLabel;
    }

    public void chartDraggedListener(ValueChangeEvent event) {
        
    }
    
    public void changeDataPointLabelActionListener(ActionEvent event) {
        //Not much to do really...
    }
    
    public void chartActionListener(ActionEvent event) {
        if (event instanceof FlotChartClickedEvent) {
            FlotChartClickedEvent flotEvent = (FlotChartClickedEvent)event;
            setClickedString("Chart Last Clicked at point (" + flotEvent.getClickedDataPoint().getX() + "," + flotEvent.getClickedDataPoint().getY() + "). Data Point index: " + flotEvent.getClickedDataPointIndex() 
                        + " on series: " + flotEvent.getClickedSeriesLabel() + ", which is series index: " + flotEvent.getClickedSeriesIndex());
            clickedDataSeriesIndex = flotEvent.getClickedSeriesIndex();
            Integer clickedDataPointIndex = flotEvent.getClickedDataPointIndex();
            XYDataList clickedList = null;
            XYDataPoint clickedPoint = null;
            
            if (clickedDataSeriesIndex != null && clickedDataSeriesIndex.equals(clickedDataSeriesIndex)) {
                clickedList = seriesDatalist.get(user_name.get(clickedDataSeriesIndex));
            }
            
            if (clickedDataPointIndex != null) {
                clickedPoint = clickedList.get(clickedDataPointIndex);
            }
            
            if (clickedPoint != null) {
                clickedDataPoint = clickedPoint;
            }
            
        } else if (event instanceof FlotChartDraggedEvent) {
            FlotChartDraggedEvent dragEvent = (FlotChartDraggedEvent)event;
            Double chartMoved = dragEvent.getDragValue();

            if (chartData.getMode().equalsIgnoreCase("Time")) {
                chartMoved /= 60000;
            }
            
            //Move the chart according to the drag-motion
            minX += chartMoved;
            maxX += chartMoved;
            
            //Ensure that minX and maxX does not go out of bounds
            if (minX < 0) { minX = 0; maxX = 10; }
            if (maxX > 100) { maxX = 100; minX = 90;}
        }
    }
    
    public void testChartDraggedAction(FlotChartDraggedEvent dragEvent) {
        Log.info("chartDraggedAction");
    }
}